package com.resurvolution.kingcloudmusicspringboot.user.service.serviceImpl;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.resurvolution.kingcloudmusicspringboot.common.constant.UserConstant;
import com.resurvolution.kingcloudmusicspringboot.common.exception.PasswordMismatchException;
import com.resurvolution.kingcloudmusicspringboot.common.exception.VerifyCodeException;
import com.resurvolution.kingcloudmusicspringboot.common.utils.BaseContext;
import com.resurvolution.kingcloudmusicspringboot.common.utils.JwtUtil;
import com.resurvolution.kingcloudmusicspringboot.user.entity.UserEntity;
import com.resurvolution.kingcloudmusicspringboot.user.vo.UserVO;
import com.resurvolution.kingcloudmusicspringboot.user.mapper.UserMapper;
import com.resurvolution.kingcloudmusicspringboot.user.service.UserService;
import com.resurvolution.kingcloudmusicspringboot.user.dto.UserDTO;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, UserEntity> implements UserService {

    @Resource
    private UserMapper userMapper;

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Resource
    private BCryptPasswordEncoder bCryptPasswordEncoder;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Resource
    private JwtUtil jwtUtil;

    @Override
    public String getQRCode(UserDTO userDTO) {
        LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(130, 50);
        redisTemplate.opsForValue().set(userDTO.getUsername(), lineCaptcha.getCode(), 60, TimeUnit.SECONDS);
        return lineCaptcha.getImageBase64Data();
    }

    @Override
    public String login(UserDTO userDTO) {
        if (!userDTO.getQrcode().equals(redisTemplate.opsForValue().get(userDTO.getUsername()))) {
            throw new VerifyCodeException();
        }
        QueryWrapper<UserEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", userDTO.getUsername());
        UserEntity userEntity = userMapper.selectOne(queryWrapper);
        if (userEntity == null) {
            userEntity = new UserEntity();
            userEntity.setUsername(userDTO.getUsername());
            userEntity.setPassword(bCryptPasswordEncoder.encode(userDTO.getPassword()));
            userEntity.setAccess(UserConstant.access);
            userEntity.setNickname(UserConstant.nickname);
            userEntity.setGender(UserConstant.gender);
            userEntity.setAvatarUrl(UserConstant.avatarUrl);
            userEntity.setRegistrationTime(LocalDateTime.now());
            userEntity.setLastLoginTime(LocalDateTime.now());
            userEntity.setEmail(UserConstant.email);
            userEntity.setPremiumMember(UserConstant.premiumMember);
            userEntity.setPremiumExpireTime(UserConstant.premiumExpireTime);
            if(userMapper.insert(userEntity) == 1) {
                return jwtUtil.generateToken(userEntity.getId(), userEntity.getPremiumMember());
            };
        }
        if (!passwordEncoder.matches(userDTO.getPassword(), userEntity.getPassword())) {
            throw new PasswordMismatchException();
        }
        String token;
        if (userEntity.getAccess() == 1) {
            token = jwtUtil.generateToken(userEntity.getId(), 1);
        } else if (userEntity.getPremiumMember() == 1) {
            token = jwtUtil.generateToken(userEntity.getId(), 2);
        } else {
            token = jwtUtil.generateToken(userEntity.getId(), 0);
        }

        return token;
    }

    @Override
    public UserVO getUserDetails() {
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(userMapper.selectById(BaseContext.getCurrentId()), userVO);
        return userVO;
    }
}
